import scapy
from scapy.all import *
from scapy.utils import PcapReader
from nfstream import NFStreamer
import pandas as pd

pd.set_option('display.max_rows', None)
pd.set_option('display.width', None)


def read_pcap(file_name): 
    print('开始读取pcap')
    packets = rdpcap(file_name)
    print('读取完成')
    return packets

#遍历文件夹中所有文件
def scaner_file(url):
    file  = os.listdir(url)
    return file

#匹配文件名是否为hostfile****.pcap
def choosefile(filename):
    if re.match(r'hostfile\d\d\d\d\.pcap',filename) != None:
        return True
    else:
        return False

def read_ip(packets):  #读取第一个SYN包的源ip
    l = len(packets)
    for i in range(l):
        if packets[i].haslayer("TCP"):
            if packets[i]['TCP'].flags == 0x02:
                ip = packets[i].payload.src
                break
    return ip

#提取特征
def Feature_extraction(dir_name,file_name,csv_name):
    my_streamer = NFStreamer(source=dir_name+file_name,
                             decode_tunnels=True,
                             bpf_filter="tcp",
                             promiscuous_mode=True,
                             snapshot_length=1536,
                             idle_timeout=120,
                             active_timeout=1800,
                             accounting_mode=3,
                             udps=None,
                             n_dissections=20,
                             statistical_analysis=True,
                             splt_analysis=0,
                             n_meters=0,
                             performance_report=0)
    dfl = my_streamer.to_pandas()[[
        # "src_ip",
        # "src_port",
        # "dst_ip",
        # "dst_port",
        # "protocol",
        "bidirectional_packets",
        "bidirectional_bytes",
        "bidirectional_first_seen_ms",
        "bidirectional_last_seen_ms",
        "bidirectional_duration_ms",
        "bidirectional_packets",
        "bidirectional_bytes",
        "src2dst_first_seen_ms",
        "src2dst_last_seen_ms",
        "src2dst_duration_ms",
        "src2dst_packets",
        "src2dst_bytes",
        "dst2src_first_seen_ms",
        "dst2src_last_seen_ms",
        "dst2src_duration_ms",
        "dst2src_packets",
        "dst2src_bytes",
        "bidirectional_min_ps",
        "bidirectional_mean_ps",
        "bidirectional_stddev_ps",
        "bidirectional_max_ps",
        "src2dst_min_ps",
        "src2dst_mean_ps",
        "src2dst_stddev_ps",
        "src2dst_max_ps",
        "dst2src_min_ps",
        "dst2src_mean_ps",
        "dst2src_stddev_ps",
        "dst2src_max_ps",
        "bidirectional_min_piat_ms",
        "bidirectional_mean_piat_ms",
        "bidirectional_stddev_piat_ms",
        "bidirectional_max_piat_ms",
        "src2dst_min_piat_ms",
        "src2dst_mean_piat_ms",
        "src2dst_stddev_piat_ms",
        "src2dst_max_piat_ms",
        "dst2src_min_piat_ms",
        "dst2src_mean_piat_ms",
        "dst2src_stddev_piat_ms",
        "dst2src_max_piat_ms",
        "bidirectional_syn_packets",
        "bidirectional_cwr_packets",
        "bidirectional_ece_packets",
        "bidirectional_urg_packets",
        "bidirectional_ack_packets",
        "bidirectional_psh_packets",
        "bidirectional_rst_packets",
        "bidirectional_fin_packets",
        "src2dst_syn_packets",
        "src2dst_cwr_packets",
        "src2dst_ece_packets",
        "src2dst_urg_packets",
        "src2dst_ack_packets",
        "src2dst_psh_packets",
        "src2dst_rst_packets",
        "src2dst_fin_packets",
        "dst2src_syn_packets",
        "dst2src_cwr_packets",
        "dst2src_ece_packets",
        "dst2src_urg_packets",
        "dst2src_ack_packets",
        "dst2src_psh_packets",
        "dst2src_rst_packets",
        "dst2src_fin_packets",
    ]]
    dfl.to_csv(dir_name+csv_name, index=False)

if __name__ == '__main__':
    dir_name = os.path.dirname(__file__) + '/'
    url = os.path.abspath(os.path.dirname(__file__))
    file = scaner_file(url)
    print(dir_name)
    for filename in file:
        if choosefile(filename):
            packets = read_pcap(dir_name+filename)
            ip = read_ip(packets)
            Feature_extraction(dir_name,filename,ip+'.csv')